package com.example.feifei.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

/**
 * 波浪动画
 * Created by feifei on 2017/7/25.
 */

public class ChuckWaveView extends View{

    /**
     * +------------------------+
     * |<--wave length->        |______
     * |   /\          |   /\   |  |
     * |  /  \         |  /  \  | amplitude
     * | /    \        | /    \ |  |
     * |/      \       |/      \|__|____
     * |        \      /        |  |
     * |         \    /         |  |
     * |          \  /          |  |
     * |           \/           | water level
     * |                        |  |
     * |                        |  |
     * +------------------------+__|____
     */

    private static final float DEFAULT_AMPLITUDE_RATIO = 0.03f; //振幅：波浪静止时水面距离底部的高度
    private static final float DEFAULT_WATER_LEVEL_RATIO = 0.5f; //水位：波浪垂直振动时偏离水面的最大距离
    private static final float DEFAULT_WAVE_LENGTH_RATIO = 1.0f; //波长：一个完整的波浪的水平长度
    private static final float DEFAULT_WAVE_SHIFT_RATIO = 0.4f; //偏移：波浪相对于初始位置的水平偏移

    private BitmapShader mWaveShader = null;
    private Matrix mShaderMatrix = null;
    private Paint mPaint;

    private float mDefaultWaterLevel = 0;
    private float mWaterLevelRatio = DEFAULT_WATER_LEVEL_RATIO;
    private float mWaveShiftRatio = DEFAULT_WAVE_SHIFT_RATIO;

    public ChuckWaveView(Context context) {
        super(context);
        intView();
    }

    public ChuckWaveView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        intView();
    }

    public ChuckWaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        intView();
    }

    private void intView(){
        mShaderMatrix = new Matrix();
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
    }

    public float getWWaveShifeRadio(){
        return mWaveShiftRatio;
    }
    public void setWaveShifeRadio(float waveShifeRadio){
        if(mWaterLevelRatio != waveShifeRadio){
            mWaterLevelRatio = waveShifeRadio;
            invalidate();
        }
    }
    public float getWaterLevelRatio() {
        return mWaterLevelRatio;
    }

    /**
     * Set water level according to <code>waterLevelRatio</code>.
     *
     * @param waterLevelRatio Should be 0 ~ 1. Default to be 0.5.
     *                        Ratio of water level to WaveView height.
     */
    public void setWaterLevelRatio(float waterLevelRatio) {
        if (mWaterLevelRatio != waterLevelRatio) {
            mWaterLevelRatio = waterLevelRatio;
            invalidate();
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        createShader();

    }
    //绘制波浪曲线
    private void createShader(){
        mDefaultWaterLevel = getHeight()*DEFAULT_WATER_LEVEL_RATIO;
        float mDefaultWaveLength = getWidth();
        float mDefaultAmplitude = getHeight()*DEFAULT_AMPLITUDE_RATIO;
        double  mDefaultAngularFrequency = 2.0f * Math.PI / DEFAULT_WAVE_LENGTH_RATIO / getWidth();

        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);

        Paint wavePaint = new Paint();
        wavePaint.setStrokeWidth(2);
        wavePaint.setAntiAlias(true);

        // y=Asin(ωx+φ)+h 正弦曲线
        final int endX = getWidth() + 1;
        final int endY = getHeight() + 1;

        float[] waveY = new float[endX];
        wavePaint.setColor(Color.parseColor("#71CFFF")); //后面的波浪
        for (int beginX = 0; beginX < endX; beginX++) {
            double wx = beginX * mDefaultAngularFrequency;
            float beginY = (float) (mDefaultWaterLevel + mDefaultAmplitude * Math.sin(wx));
            canvas.drawLine(beginX, beginY, beginX, endY, wavePaint);

            waveY[beginX] = beginY;
        }

        wavePaint.setColor(Color.parseColor("#37BFFF")); //前面的波浪
        final int wave2Shift = (int) (mDefaultWaveLength / 4);
        for (int beginX = 0; beginX < endX; beginX++) {
            canvas.drawLine(beginX, waveY[(beginX + wave2Shift) % endX], beginX, endY, wavePaint);
        }

        //将波浪曲线的Bitmap变量赋值给画笔
        mWaveShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
        mPaint.setShader(mWaveShader);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        if(mWaveShader!=null){
            if (mPaint.getShader() == null) {
                mPaint.setShader(mWaveShader);
            }
            // scale shader according to mWaveLengthRatio and mAmplitudeRatio
            // this decides the size(mWaveLengthRatio for width, mAmplitudeRatio for height) of waves
            mShaderMatrix.setScale(1, 1, 0, mDefaultWaterLevel);

            // translate shader according to mWaveShiftRatio and mWaterLevelRatio
            // this decides the start position(mWaveShiftRatio for x, mWaterLevelRatio for y) of waves
            mShaderMatrix.postTranslate(mWaveShiftRatio * getWidth(), (DEFAULT_WATER_LEVEL_RATIO - mWaterLevelRatio) * getHeight());

            // assign matrix to invalidate the shader
            mWaveShader.setLocalMatrix(mShaderMatrix);

            canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
        }else{
            mPaint.setShader(null);
        }
    }
}
